﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web.Security;

using Microsoft.WindowsAzure.StorageClient;

using Canyala.Lagoon.Extensions;

namespace Canyala.Lagoon.Entities
{
    public class UserAccount : TableServiceEntity
    {
        /// <summary>
        /// Unique identity for the user account.
        /// </summary>
        public Guid Id { get; set; }

        public string Claims { get; set; }
        public string Hash { get; set; }
        public string Hint { get; set; }
        public string Salt { get; set; }

        public static UserAccount Create(string domain, string user, string password, string hint, string[] claims)
        {
            var salt = CreateSalt(7);

            return new UserAccount
            {
                Id = Guid.NewGuid(),
                PartitionKey = domain,
                RowKey = user,
                Salt = salt,
                Hash = CreatePasswordHash(password, salt),
                Claims = claims.Join(';'),
                Hint = hint
            };
        }

        public string GetDomain()
        {
            return PartitionKey;
        }

        public string GetUser()
        {
            return RowKey;
        }

        public bool IsAuthorized(string password)
        {
            return Hash == CreatePasswordHash(password, Salt);
        }

        private static string CreateSalt(int size)
        {
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            byte[] buff = new byte[size];
            rng.GetBytes(buff);

            return Convert.ToBase64String(buff);
        }

        private static string CreatePasswordHash(string password, string salt)
        {
            string saltAndPassword = String.Concat(password, salt);
            string hashedPassword = FormsAuthentication.HashPasswordForStoringInConfigFile(saltAndPassword, "SHA1");
            hashedPassword = String.Concat(hashedPassword, salt);
            return hashedPassword;
        }
    }
}
